<?php


namespace app\api\controller;


use app\api\model\AdminRole;
use app\api\model\SystemRole;
use app\api\model\SystemRoleMenu;
use app\common\controller\Api;
use app\common\controller\OperationLog;
use think\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\DbException;
use think\Request;

class Role extends Api
{
    /**
     * @var bool 无需登录的方法
     */
    protected $noNeedLogin = [];

    /**
     * @var bool 无需鉴权的方法
     */
    protected $noNeedAuth = [];

    /**
     * @var array 无需token的方法
     */
    protected $noNeedToken = [];

    /**
     * 查询角色列表方法
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws Exception
     */
    public function lists()
    {
        // 定义日志参数
        $options = array(
            'title' => '获取角色列表',
            'method' => Request::instance()->action(),
            'request_method' => Request::instance()->method(),
            'open_url' => Request::instance()->url(),
            'oper_ip' => Request::instance()->ip(),
            'token' => Request::instance()->header('token')
        );
        $roleList = SystemRole::all();
        foreach ($roleList as &$v) {
            $v['number'] = Db::name('admin_role')
                ->where('role_id', '=', $v['id'])
                ->count('admin_id');
        }
        OperationLog::OperSuccess([], $options, 'R', $roleList);
        $this->success('success', ['code' => 200, 'data' => $roleList]);
    }

    /**
     * 角色添加方法
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function add()
    {
        // 定义日志参数
        $options = array(
            'title' => '添加角色',
            'method' => Request::instance()->action(),
            'request_method' => Request::instance()->method(),
            'open_url' => Request::instance()->url(),
            'oper_ip' => Request::instance()->ip(),
            'token' => Request::instance()->header('token')
        );
        $param = Request::instance()->param() ?? [];
        $validRes = $this->validate($param, 'SystemRole.add');
        if ($validRes !== true) {
            OperationLog::OperError($param, $options, 'C', $validRes);
            $this->error('error', ['code' => 201, 'data' => $validRes]);
        }
        $checkNameExist = SystemRole::get(['name' => trim($param['name'])]);
        if (!empty($checkNameExist)) {
            OperationLog::OperError($param, $options, 'C', '存在重复的角色名!');
            $this->error('error', ['code' => 201, 'data' => '存在重复的角色名!']);
        }
        Db::startTrans();
        try {
            $role = new SystemRole();
            $role->save($param);
            Db::commit();
            OperationLog::OperSuccess($param, $options, 'C', '操作成功!');
            $this->success('success', ['code' => 200, 'data' => '操作成功!']);
        } catch (Exception $e) {
            Db::rollback();
            OperationLog::OperError($param, $options, 'C', $e->getMessage());
            $this->error('error', $e->getMessage(), 202);
        }
    }

    /**
     * 查看角色详情
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function detail()
    {
        // 定义日志参数
        $options = array(
            'title' => '获取角色详情',
            'method' => Request::instance()->action(),
            'request_method' => Request::instance()->method(),
            'open_url' => Request::instance()->url(),
            'oper_ip' => Request::instance()->ip(),
            'token' => Request::instance()->header('token')
        );
        $param = Request::instance()->param() ?? [];
        $validRes = $this->validate($param, 'SystemRole.detail');
        if ($validRes !== true) {
            OperationLog::OperError($param, $options, 'R', $validRes);
            $this->error('error', ['code' => 201, 'data' => $validRes]);
        }
        $checkRoleExist = SystemRole::get(['id' => $param['id']])->hidden(['create_time', 'update_time']);
        if (empty($checkRoleExist)) {
            OperationLog::OperError($param, $options, 'R', '角色信息不存在!');
            $this->error('error', ['code' => 201, 'data' => '角色信息不存在!']);
        }
        OperationLog::OperSuccess($param, $options, 'R', $checkRoleExist);
        $this->success('success', ['code' => 200, 'data' => $checkRoleExist]);
    }

    /**
     * 修改角色
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function edit()
    {
        // 定义日志参数
        $options = array(
            'title' => '修改角色信息',
            'method' => Request::instance()->action(),
            'request_method' => Request::instance()->method(),
            'open_url' => Request::instance()->url(),
            'oper_ip' => Request::instance()->ip(),
            'token' => Request::instance()->header('token')
        );
        $param = Request::instance()->param() ?? [];
        $validRes = $this->validate($param, 'SystemRole.edit');
        if ($validRes !== true) {
            OperationLog::OperError($param, $options, 'U', $validRes);
            $this->error('error', ['code' => 201, 'data' => $validRes]);
        }
        $checkExistRole = SystemRole::get(['name' => $param['name']]);
        if (!empty($param['name']) && ($checkExistRole['id'] != $param['id'])) {
            OperationLog::OperError($param, $options, 'U', '存在重复的角色!');
            $this->error('error', ['code' => 201, 'data' => '存在重复的角色!']);
        }
        $role = SystemRole::get(['id' => $param['id']]);
        if (empty($role)) {
            OperationLog::OperError($param, $options, 'U', '角色不存在!');
            $this->error('error', ['code' => 201, 'data' => '角色不存在!']);
        }
        Db::startTrans();
        try {
            $role->save($param, ['id' => $param['id']]);
            Db::commit();
            OperationLog::OperSuccess($param, $options, 'U', '角色修改成功!');
            $this->success('success', ['code' => 200, 'data' => '操作成功']);
        } catch (Exception $e) {
            Db::rollback();
            OperationLog::OperError($param, $options, 'U', $e->getMessage());
            $this->error('error', $e->getMessage(), 202);
        }
    }

    /**
     * 角色分配权限
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function grant_auth()
    {
        // 定义日志参数
        $options = array(
            'title' => '给角色分配权限',
            'method' => Request::instance()->action(),
            'request_method' => Request::instance()->method(),
            'open_url' => Request::instance()->url(),
            'oper_ip' => Request::instance()->ip(),
            'token' => Request::instance()->header('token')
        );
        $param = Request::instance()->param() ?? [];
        $validRes = $this->validate($param, 'SystemRoleMenu.add');
        if ($validRes !== true) {
            OperationLog::OperError($param, $options, 'U', $validRes);
            $this->error('error', ['code' => 201, 'data' => $validRes]);
        }
        Db::startTrans();
        try {
            // 先删除已存在信息,再赋新值
            SystemRoleMenu::where(['role_id' => $param['role_id']])->delete();
            $systemRoleMenu = new SystemRoleMenu();
            $systemRoleMenu->insertAll($param['menu_ids']);
            Db::commit();
            OperationLog::OperSuccess($param, $options, 'U', '分配权限成功!');
            $this->success('success', ['code' => 200, 'data' => '操作成功!']);
        } catch (Exception $e) {
            Db::rollback();
            OperationLog::OperError($param, $options, 'U', $e->getMessage());
            $this->error('error', $e->getMessage(), 202);
        }
    }

    /**
     * 获取角色权限
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function get_grant_auth()
    {
        // 定义日志参数
        $options = array(
            'title' => '获取角色权限',
            'method' => Request::instance()->action(),
            'request_method' => Request::instance()->method(),
            'open_url' => Request::instance()->url(),
            'oper_ip' => Request::instance()->ip(),
            'token' => Request::instance()->header('token')
        );
        $param = Request::instance()->param() ?? [];
        $validRes = $this->validate($param, 'SystemRoleMenu.detail');
        if ($validRes !== true) {
            OperationLog::OperError($param, $options, 'R', $validRes);
            $this->error('error', ['code' => 201, 'data' => $validRes]);
        }
        $systemRoleMenu = SystemRoleMenu::all(['role_id' => $param['role_id']]);
        OperationLog::OperSuccess($param, $options, 'R', $systemRoleMenu);
        $this->success('success', ['code' => 200, 'data' => $systemRoleMenu]);
    }

    /**
     * Admin删除方法
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function del()
    {
        // 定义日志参数
        $options = array(
            'title' => '删除角色权限',
            'method' => Request::instance()->action(),
            'request_method' => Request::instance()->method(),
            'open_url' => Request::instance()->url(),
            'oper_ip' => Request::instance()->ip(),
            'token' => Request::instance()->header('token')
        );
        $param = Request::instance()->param() ?? [];
        $validRes = $this->validate($param, 'SystemRole.del');
        if ($validRes !== true) {
            OperationLog::OperError($param, $options, 'D', $validRes);
            $this->error('error', ['code' => 201, 'data' => $validRes]);
        }
        // 判断当前角色是否存在角色账户
        $findExistAdmin = AdminRole::get(['role_id' => $param['id']]);
        if (!empty($findExistAdmin)) {
            OperationLog::OperError($param, $options, 'D', '当前角色有对应账户,无法删除!');
            $this->error('error', ['code' => 201, 'data' => '当前角色有对应账户,无法删除!']);
        }
        // 判断当前角色是否存在
        $checkExistRole = SystemRole::get(['id' => $param['id']]);
        if (empty($checkExistRole)) {
            OperationLog::OperError($param, $options, 'D', '对应角色不存在!');
            $this->error('error', ['code' => 201, 'data' => '对应角色不存在!']);
        }
        Db::startTrans();
        try {
            $checkExistRole->delete(true);
            Db::commit();
            OperationLog::OperSuccess($param, $options, 'D', '操作成功!');
            $this->success('success', ['code' => 200, 'data' => '操作成功!']);
        } catch (Exception $e) {
            OperationLog::OperError($param, $options, 'D', $e->getMessage());
            $this->error('error', $e->getMessage(), 202);
        }
    }
}